
#ifndef __HOOK_API_H__
#define __HOOK_API_H__

#include "base.h"
#include "Detours/detours.h"
#include <winternl.h>


typedef enum {
    ObjectNone = 0,
    ObjectEvent,
    ObjectMutant,
    ObjectSemaphore,
    ObjectSection,
    ObjectFile,
    ObjectPartition,
    ObjectMailslot,
    ObjectNamePipe,
    ObjectLPC,
    ObjectALPC,
    ObjectService,
    ObjectProcess,
    ObjectThread,
    ObjectWindow,
}OBJECT_TYPE_CLASS;

extern int gSuffixLenghtA;
extern int gSuffixLenghtW;

//#define CHECK_STATUS(__s, __t)   if((__s) == (__s) && (__t) == (__t))
#define CHECK_STATUS(__s, __t)   if(0 > (__s) && (__t) == (__t))
#define CHECK_ERROR(__e, __t)   if(0 != (__e) && (__t) == (__t))

typedef struct __APIINFO
{
    char strFunction[64];
    void** pRealFunction;
    void* pHookFunction;
    void* pSrcFunction;
    unsigned char HookBuffer[5];
}APIINFO;

typedef std::map<std::wstring, std::vector<APIINFO>*, ci_lessW> HookInfo;

std::vector<APIINFO>* GetAPIInfo(const wchar_t* strModule);
void ClearAPIInfo(const wchar_t* strModule);

bool HookAPI(std::vector<APIINFO>& vecInfo, const char* strFunction,
    void* pSrcFunction, void* pHookFunction, void** pRealFunction);
#define HOOKAPI(_v, _f) HookAPI(_v, #_f, NULL, (void*)HOOK_##_f, (void**)&REAL_##_f)
#define HOOKAPI2(_v, _f) HookAPI(_v, #_f, (void*)_f, (void*)HOOK_##_f, (void**)&REAL_##_f)

int AttachCommit();
int DetachCommit();

int CommitHook(const wchar_t* strModule, std::vector<APIINFO>& vecInfo);
int CommitUnHook(const wchar_t* strModule, std::vector<APIINFO>& vecInfo);


BOOL SkipObjectName(LPCWSTR ObjectName, LONG Size, ACCESS_MASK DesiredAccess, 
    OBJECT_TYPE_CLASS ObjectType);

BOOL CreateSafeBoxObjectName(CONST PUNICODE_STRING ObjectName, PUNICODE_STRING BoxObjectName,
    ACCESS_MASK DesiredAccess, OBJECT_TYPE_CLASS ObjectType, BOOL CheckSkip);

BOOL ClonePrefixName(PUNICODE_STRING ObjectName, CONST PUNICODE_STRING BoxObjectName, BOOL SkipSuffix);

#endif